// 获取dom
const can = document.getElementById('canvas')
const ctx = can.getContext('2d')
// 定义颜色
const colors = ['#E14767', '#FF7300', '#00BBFF', '#FF00F2', '#FF72C9', '#FF1D1D']
/**
 * 创建圆
 * @param {ctx} ctx 实例
 * @param {number} x x轴
 * @param {number} y y轴
 * @param {number} r 半径
 */
 function createCircular(ctx, x, y, r, color) {
  // arc 参数文档 https://www.w3school.com.cn/tags/canvas_arc.asp
  ctx.arc(x, y, r, 0, 2 * Math.PI, false)
  ctx.fillStyle = color
  ctx.fill()
}

/**
 * 初始化
 * @param {number} createNum 爆炸后生成的数量
 * @param {number} rMax 规定鼠标悬浮时球半径的最大值
 * @param {number} mouseScope 规定鼠标悬浮时 多少半径内会变大
 * @param {number} width 宽度
 * @param {number} height 高度
 */
function init(createNum, width = document.body.clientWidth, height = document.body.clientHeight) {
  const w = width
  const h = height

  can.width = w
  can.height = h

  /**
 * 创建椭圆
 * @param {number} x 目标X
 * @param {number} y 目标y
 */
  function createEllipse(x, y) {
    this.x = x
    this.y = h
    this.color = colors[Math.ceil(Math.random() * colors.length - 1)]
    // 初始速度
    this.startY = 1
    const explode = new explodeFun(x, y, 5, this.color)
    // 绘制
    this.draw = () => {
      // 重新绘制路径 https://www.w3school.com.cn/tags/canvas_beginpath.asp
      ctx.beginPath()
      let gradient=ctx.createLinearGradient(0, this.y + 200, 0, 0); //创建一个渐变色线性对象
      gradient.addColorStop(0, '#FFFCD3');                  //定义渐变色颜色
      gradient.addColorStop(1,'#FE9A2F');
      ctx.ellipse(this.x, this.y,4,20,0,0,Math.PI*2);
      ctx.fillStyle = gradient;
      ctx.fill();
    }

    this.update = (index) => {
      this.startY += 0.5
      this.y -= this.startY
    
      if (this.y < y) {
        explode.update(index)
        return
        // console.log('删除');
        // ellipseArray.splice(index, 1)
      }
      this.draw()
    }
  }

  /**
   * 爆炸效果2
   * @param {number} x
   * @param {number} y
   * @param {number} r 半径
   */
  function splashesFun(x, y, r, color) {
    this.x = x
    this.y = y
    this.r = Math.random() * r

    this.oldX = ''
    this.oldY = ''

    const random = Math.random() * 10

    this.draw = () => {
      ctx.beginPath()
      createCircular(ctx, this.x, this.y, this.r / 2, color)
    }

    /**
     * 
     * @param {number} index 第几个ellipseArray
     * @param {number} i 第几个splashes
     */
    this.update = (index, i) => {
      if ((this.x < 0 || this.x > w) && (this.y > h || this.y < 0)) {
        ellipseArray.splice(index, 1)
      }
      this.x = Math.cos( random * 10 * i * 2 * Math.PI / 5) * 5 + this.x
      this.y = Math.sin( random * 10 * i * 2 * Math.PI / 5) * 5 + this.y
      this.draw()

      let aX =  this.x + Math.random() * 2
      let aY = this.y + Math.random() * 2
      ctx.beginPath()
      createCircular(ctx, aX, aY, this.r / 4 , 'rgba(255, 255, 255, 0.6)')
    }
  }

  /**
   * 爆炸效果
   * @param {number} x
   * @param {number} y
   * @param {number} r 半径
   */
  function explodeFun(x, y, r, color) {
    this.x = x
    this.y = y
    this.r = r
    this.maxR = 10
    this.splashes = new Array(createNum).fill('').map(item => new splashesFun(this.x, this.y, 15, color))

    this.draw = () => {
      // 绘制
      ctx.beginPath()
      createCircular(ctx, this.x, this.y, this.r, color)
    }

    this.update = (index) => {
      this.r += 1
      if (this.r >= this.maxR) {
        this.r = this.maxR

        // 绘制爆炸后效果
        this.splashes.forEach((item, i) => {
          item.update(index, i + 1)
        })
        return
      }
      this.draw()
    }
  }

  // 所有球所在位置
  const ellipseArray = []
  can.addEventListener("click", (e) => {
    isClear = true
    ellipseArray.push(new createEllipse(e.x, e.y))
  })

  // 生成球
  function animate() {
    requestAnimationFrame(animate)
    // 清除像素 https://www.w3school.com.cn/tags/canvas_clearrect.asp
    ctx.fillStyle = 'rgba(0,0,0,0.1)'
    ctx.fillRect(0, 0, w, h)
    // 初始化未爆炸的烟花
    ellipseArray.forEach((ball, index) => {
      ball.update(index)
    })
  }
  animate()
}